﻿#include "SDL_Platform.h"
#include "SDL_Canvas.h"

#define CLO_SDL_INIT_FLAG		SDL_INIT_VIDEO | SDL_INIT_TIMER

SDL_CPlatform::SDL_CPlatform()
{
	m_pMainSurface = NULL;
}

SDL_CPlatform::~SDL_CPlatform()
{
}

bool SDL_CPlatform::InitPlatform(GAF_CBundle* pParam)
{
	// 初始化SDL
	if(SDL_WasInit(CLO_SDL_INIT_FLAG) == -1)
	{
		return true;
	}

	// 初始化SDL
	if(SDL_Init(CLO_SDL_INIT_FLAG) == -1)
	{
		GAF_ERROR("Init SDL Error!\n", "");
		return false;
	}

	// 
// 	if(IMG_Init(IMG_INIT_JPG | IMG_INIT_PNG | IMG_INIT_TIF) == -1)
// 	{
// 		GAF_ERROR("Init SDL_Image Error!\n", "");
// 		return false;
// 	}

	// 初始化TTF
	if(TTF_Init() == -1)
	{
		GAF_ERROR("Init SDL_TTF Error!\n", "");
		return false;
	}

	return true;
}

bool SDL_CPlatform::DestroyPlatform()
{
	atexit(TTF_Quit);	// 程序崩溃时，也可以卸载SDL_TTF
	atexit(IMG_Quit);	// 程序崩溃时，也可以卸载SDL_Image
	atexit(SDL_Quit);	// 程序崩溃时，也可以卸载SDL

	return true;
}

GAF_DWindowHandle SDL_CPlatform::NewWindow(GAF_SCreateWindow& cw)
{
	GAF_CHECK_R(m_pMainSurface == NULL, m_pMainSurface);

	SDL_Surface* _hSDLWindow = NULL;

	unsigned long _lVideoFlags = 0;
	_lVideoFlags |= SDL_HWSURFACE;			// 显卡存储
	_lVideoFlags |= SDL_DOUBLEBUF;			// 双缓冲
	
	// 全屏幕
	if(cw.isFullScreen)
	{
		_lVideoFlags |= SDL_FULLSCREEN;
	}

	// 无边框
	if(cw.isNoFrame && !cw.isFullScreen)
	{
		_lVideoFlags |= SDL_NOFRAME;
	}

	// 可缩放
	if(cw.isScalable && !cw.isNoFrame && !cw.isFullScreen)
	{
		_lVideoFlags |= SDL_RESIZABLE;
	}

	// 窗口居中
	if(cw.isCenter && !cw.isFullScreen)
	{
		putenv("SDL_VIDEO_WINDOW_POS");
		putenv("SDL_VIDEO_CENTERED = 1");
	}

	SDL_DPixelBit _pb = cw.bdlOther.GetInteger("PixelBit");
	if((_hSDLWindow = SDL_SetVideoMode(cw.nWidth, cw.nHeight, _pb, _lVideoFlags)) == NULL)
		return NULL;

	if(m_pMainSurface == NULL)
	{
		m_pMainSurface = _hSDLWindow;
	}

	SetWindowTitle(m_pMainSurface, cw.strTitle);

	return _hSDLWindow;
}

bool SDL_CPlatform::ShowWindow(GAF_DWindowHandle hWindow)
{
	return true;
}

bool SDL_CPlatform::HideWindow(GAF_DWindowHandle hWindow)
{
	return true;
}

void SDL_CPlatform::RanderWindow(GAF_DWindowHandle hWindow)
{
	return;
}

void SDL_CPlatform::FlipWindow(GAF_DWindowHandle hWindow)
{
	SDL_Flip((SDL_Surface*)hWindow);
}

bool SDL_CPlatform::DeleteWindow(GAF_DWindowHandle hWindow)
{
	SDL_DWindowHandle _hSDLWindow = (SDL_DWindowHandle)hWindow;
	if(m_pMainSurface == _hSDLWindow)
	{
// 		SAFE_RELEASE(m_pMainSurface);
	}
	else
	{
// 		SAFE_RELEASE(_hSDLWindow);
	}

	return true;
}

void SDL_CPlatform::SetWindowTitle(GAF_DWindowHandle hWindow, STD_STRING strTitle)
{
	GAF_CHECK(strTitle != "");

	SDL_WM_SetCaption((strTitle + " - SDL").c_str(), NULL);
}

GAF_CCanvas* SDL_CPlatform::NewCanvas(GAF_DWindowHandle hWindow)
{
	GAF_CCanvas* pCanvas = new SDL_CCanvas();
	if(!pCanvas->Init(hWindow))
	{
		delete pCanvas;
	}

	return pCanvas;
}

bool SDL_CPlatform::DeleteCanvas(GAF_CCanvas* pCanvas)
{
	delete pCanvas; //GAF_DELETE(pCanvas);
	return true;
}

bool SDL_CPlatform::GetCommand(GAF_DWindowHandle hWindow, GAF_SCommand& cmdGet)
{
	static SDL_Event s_SDLEvent;

	if(SDL_PollEvent(&s_SDLEvent) == 1)
	{
// 		GAF_NOTE("SDL Command Type = %d\n", s_SDLEvent.type);

		cmdGet.Reset();

		switch(s_SDLEvent.type)
		{
		case SDL_QUIT:
			cmdGet.nCmdID = GAF_COMMAND_QUIT;
			break;
		case SDL_KEYDOWN:
			cmdGet.nCmdID = GAF_COMMAND_KEY_DOWN;
			cmdGet.lParam1 = cmdGet.lParam2 = (long)s_SDLEvent.key.keysym.sym;
			break;
		case SDL_KEYUP:
			cmdGet.nCmdID = GAF_COMMAND_KEY_UP;
			cmdGet.lParam1 = cmdGet.lParam2 = (long)s_SDLEvent.key.keysym.sym;
			break;
		case SDL_MOUSEBUTTONDOWN:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_DOWN;
			cmdGet.lParam1 = (long)s_SDLEvent.button.button;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.button.x, s_SDLEvent.button.y);
			break;
		case SDL_MOUSEBUTTONUP:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_UP;
			cmdGet.lParam1 = (long)s_SDLEvent.button.button;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.button.x, s_SDLEvent.button.y);
			break;
		case SDL_MOUSEMOTION:
			cmdGet.nCmdID = GAF_COMMAND_CURSOR_MOVE;
			cmdGet.lParam1 = (long)s_SDLEvent.motion.state;
			cmdGet.lParam2 = GAF_PARAM_MAKE(s_SDLEvent.motion.x, s_SDLEvent.motion.y);
			break;
		default:
			return false;
		}
		return true;
	}
	return false;
}

void SDL_CPlatform::ClearCommandBuffer(GAF_DWindowHandle hWindow)
{
	SDL_Event SDLEvent;
	while(SDL_PollEvent(&SDLEvent) == 1)
	{}
}

GAF_DImageHandle SDL_CPlatform::NewImage(const STD_STRING strFile, GAF_SImageInfo& _OUT ii)
{
	SDL_Surface* _psfNew = ReadSurface(strFile);

	if(_psfNew != NULL)
	{
		ii.nWidth = _psfNew->w;
		ii.nHeight = _psfNew->h;
		ii.nBitsPixel = _psfNew->format->BitsPerPixel;
	}

	return _psfNew;
}
GAF_DImageHandle SDL_CPlatform::NewImage(const void* pData, const SIZET nSize, GAF_SImageInfo& _OUT ii)
{
	SDL_Surface* _psfNew = LoadSurface((void*)pData, nSize);

	if(_psfNew != NULL)
	{
		ii.nWidth = _psfNew->w;
		ii.nHeight = _psfNew->h;
		ii.nBitsPixel = _psfNew->format->BitsPerPixel;
	}

	return _psfNew;
}

GAF_DImageHandle SDL_CPlatform::NewImage(const UINT nWidth, const UINT nHeight,	GAF_SImageInfo& _OUT ii)
{
	SDL_Surface* _psfNew = CreateSurface(nWidth, nHeight);

	if(_psfNew != NULL)
	{
		ii.nWidth = _psfNew->w;
		ii.nHeight = _psfNew->h;
		ii.nBitsPixel = _psfNew->format->BitsPerPixel;
	}

	return _psfNew;
}

bool SDL_CPlatform::GetImageInfo(GAF_DImageHandle hImage, GAF_SImageInfo& _OUT ii)
{
	GAF_CHECK_R(hImage != NULL, false);

	SDL_Surface* _psfImage = (SDL_Surface*)hImage;
	ii.nWidth = _psfImage->w;
	ii.nHeight = _psfImage->h;
	ii.nBitsPixel = _psfImage->format->BitsPerPixel;

	return true;
}

bool SDL_CPlatform::DeleteImage(GAF_DImageHandle hImage)
{
	GAF_CHECK_R(hImage != NULL, false);
	DeleteSurface((SDL_Surface*)hImage);
	return true;
}

// GAF_CAudio* SDLPlatform::CreateAudio(GAF_CBundle* pBundle)
// {
// 	CSDLAudio* pAudio = GAF_NEW(CSDLAudio);
// 
// 	if(!pAudio->Init(pBundle))
// 	{
// 		CLO_ERROR_INIT_CLASS(CLO_CSDLAudio);
// 		GAF_DELETE(pAudio);
// 		return NULL;
// 	}
// 	
// 	return pAudio;
// }
// 
// bool SDLPlatform::PlayAudio(const _STRING strPathName, bool isLoop)
// {
// 	return false;
// }

GAF_DTimeTicks SDL_CPlatform::GetTimeTicks()
{
	return SDL_GetTicks();
}

void SDL_CPlatform::Delay(GAF_DTimeTicks ttSleep)
{
	return SDL_Delay(ttSleep);
}

SDL_Surface* SDL_CPlatform::CreateSurface( int nWidth, int nHeight )
{
	SDL_Surface* _pNew = SDL_CreateRGBSurface(SDL_HWSURFACE, nWidth, nHeight, SDL_PIXELBIT_32,
		0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);

	return FormatSurface(_pNew);
}

SDL_Surface* SDL_CPlatform::ReadSurface( STD_STRING strFile )
{
	SDL_Surface* _pNew = IMG_Load(strFile.c_str());

	return FormatSurface(_pNew);
}

SDL_Surface* SDL_CPlatform::LoadSurface( void* pData, SIZET nSize )
{
	SDL_RWops* pRW = SDL_RWFromMem(pData, nSize);
	SDL_Surface* _pNew = IMG_Load_RW(pRW, 0);

	return FormatSurface(_pNew);
}

void SDL_CPlatform::DeleteSurface( SDL_Surface* psfDelete )
{
	SDL_FreeSurface(psfDelete);
}

SDL_Surface* SDL_CPlatform::FormatSurface(SDL_Surface* psfSrc)
{
	// 这一步，有助于大幅度优化渲染速度。

	GAF_CHECK_R(psfSrc != NULL, NULL);
	SDL_Surface* _psfFormat = SDL_DisplayFormatAlpha(psfSrc);
	DeleteSurface(psfSrc);
	return _psfFormat;
}
